package com.wr.springbootRabbitMq.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.configurationprocessor.json.JSONException;
import org.springframework.boot.configurationprocessor.json.JSONObject;
import org.springframework.stereotype.Service;

import java.util.UUID;

@Service
@Slf4j
public class OrderServiceImpl {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 模拟用户下单(fanout模式)
     * @param userId 用户id
     * @param produceId 商品id
     * @param num 商品数量
     */
    public void orderFanout(String userId, String produceId, int num) throws JSONException {
        // 1、根据商品id查询库存数量是否足够
        // 2、保存订单
//        String orderId = UUID.randomUUID().toString().replaceAll("-","");
        // 模拟json
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("id",UUID.randomUUID().toString().replaceAll("-",""));
        jsonObject.put("name","张三");
        // 3、通过mq来发送消息
        //
        String exchangeName = "fanout-order-exchange";
        String routingKey1 = "";

        // 4.设置消息的可靠投递
        rabbitTemplate.setConfirmCallback((data,ack,cause)->{
            if (!ack) {
                log.error("消息发送失败!" + cause + data.toString());
            } else {
                log.info("消息发送成功,消息ID：" + (data != null ? data.getId() : null));
            }
        });
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
            log.info("消息丢失:exchange({}),route({}),replyCode({}),replyText({}),message:{}", exchange, routingKey, replyCode, replyText, message);
        });


        rabbitTemplate.convertAndSend(exchangeName,routingKey1,jsonObject.toString());
    }

    /**
     * 模拟用户下单(direct模式)
     * @param userId 用户id
     * @param produceId 商品id
     * @param num 商品数量
     */
    public void orderDirect(String userId, String produceId, int num){
        // 1、根据商品id查询库存数量是否足够
        // 2、保存订单
        String orderId = UUID.randomUUID().toString().replaceAll("-","");
        // 3、通过mq来发送消息
        //
        String exchangeName = "direct-order-exchange";
        String routingKey = "sms";
        rabbitTemplate.convertAndSend(exchangeName,routingKey,orderId);
    }

    /**
     * 模拟用户下单(topic模式)
     * @param userId 用户id
     * @param produceId 商品id
     * @param num 商品数量
     */
    public void orderTopic(String userId, String produceId, int num){
        // 1、根据商品id查询库存数量是否足够
        // 2、保存订单
        String orderId = UUID.randomUUID().toString().replaceAll("-","");
        // 3、通过mq来发送消息
        //
        String exchangeName = "topic-order-exchange";
        String routingKey = "sms.jjj";
        rabbitTemplate.convertAndSend(exchangeName,routingKey,orderId);
        rabbitTemplate.convertAndSend(exchangeName,"kk.email",orderId);
    }

    /**
     * 模拟用户下单(direct模式的过期队列)
     * @param userId 用户id
     * @param produceId 商品id
     * @param num 商品数量
     */
    public void orderDirectTTL(String userId, String produceId, int num){
        // 1、根据商品id查询库存数量是否足够
        // 2、保存订单
        String orderId = UUID.randomUUID().toString().replaceAll("-","");
        // 3、通过mq来发送消息
        //
        String exchangeName = "direct-order-ttl-exchange";
        String routingKey = "sms";
        rabbitTemplate.convertAndSend(exchangeName,routingKey,orderId);
    }

    /**
     * 模拟用户下单(direct模式的单条消息过期时间设置)
     * @param userId 用户id
     * @param produceId 商品id
     * @param num 商品数量
     */
    public void orderDirectTTLMessage(String userId, String produceId, int num){
        // 1、根据商品id查询库存数量是否足够
        // 2、保存订单
        String orderId = UUID.randomUUID().toString().replaceAll("-","");
        // 3、通过mq来发送消息
        //
        String exchangeName = "direct-order-ttl-exchange";
        String routingKey = "ttlMessage";

        // 设置消息过期时间
//        MessagePostProcessor messagePostProcessor = new MessagePostProcessor() {
//            @Override
//            public Message postProcessMessage(Message message) throws AmqpException {
//                message.getMessageProperties().setExpiration("5000");
//                message.getMessageProperties().setContentEncoding("utf-8");
//                return message;
//            }
//        };
        rabbitTemplate.convertAndSend(exchangeName,routingKey,orderId,(message)->{
            message.getMessageProperties().setExpiration("5000");
            message.getMessageProperties().setContentEncoding("utf-8");
            return message;
        });
    }
}
